package com.df.blueben.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.df.blueben.constant.DefaultUserConstant;
import com.df.blueben.constant.JwtClaimsConstant;
import com.df.blueben.exception.BusinessException;
import com.df.blueben.exception.ErrorCode;
import com.df.blueben.model.dto.UserLoginDto;
import com.df.blueben.model.dto.UserRegisterDto;
import com.df.blueben.model.entity.Users;
import com.df.blueben.model.vo.UserVo;
import com.df.blueben.properties.JwtProperties;
import com.df.blueben.service.UsersService;
import com.df.blueben.mapper.UsersMapper;
import com.df.blueben.utils.JwtUtil;
import com.df.blueben.utils.PasswordUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
* @author Administrator
* @description 针对表【users】的数据库操作Service实现
* @createDate 2025-06-30 19:00:33
*/
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users>
    implements UsersService{

    @Autowired
    JwtProperties jwtProperties;
    @Override
    public UserVo userLogin(UserLoginDto userLoginDto) {

        if(userLoginDto == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户名或密码不能为空");
        }
        if(userLoginDto.getUsername() == null || userLoginDto.getPassword() == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户名或密码不能为空");
        }

        //根据用户名查询用户
        Users user = lambdaQuery().eq(Users::getUsername, userLoginDto.getUsername()).one();
        if(user == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户名或密码错误");
        }

        //先将密码进行加密
        PasswordUtils.hashPassword(userLoginDto.getPassword());
        //判断密码是否匹配
        if(!PasswordUtils.checkPassword(userLoginDto.getPassword(),user.getPassword())){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户名或密码错误");
        }

        //登录成功后，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, user.getId());
        String token = JwtUtil.createJWT(
                jwtProperties.getUserSecretKey(),
                jwtProperties.getUserTtl(),
                claims);
        //将用户信息封装到UserVO中
        UserVo userVo = new UserVo();
        userVo.setId(user.getId());
        userVo.setUsername(user.getUsername());
        userVo.setEmail(user.getEmail());
        userVo.setAvatarUrl(user.getAvatarUrl());
        userVo.setNickname(user.getNickname());
        userVo.setBio(user.getBio());
        userVo.setToken(token);
        return userVo;
    }

    @Override
    public Integer userRegister(UserRegisterDto userRegisterDto) {
        if(userRegisterDto == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户名或密码不能为空");
        }
        if(userRegisterDto.getUsername() == null || userRegisterDto.getPassword() == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户名或密码不能为空");
        }
        if(userRegisterDto.getEnsurePassword() == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"确认密码不能为空");
        }
        if(!userRegisterDto.getPassword().equals(userRegisterDto.getEnsurePassword())){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"两次密码不一致");
        }
        //根据用户名查询用户
        Users user = lambdaQuery().eq(Users::getUsername, userRegisterDto.getUsername()).one();
        if(user != null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户名已存在");
        }
        //将密码进行加密
        String password = PasswordUtils.hashPassword(userRegisterDto.getPassword());
        //将用户信息封装到Users中
        Users users = new Users();
        users.setUsername(userRegisterDto.getUsername());
        users.setPassword(password);
        users.setNickname(DefaultUserConstant.DEFAULT_USER_NICKNAME + UUID.randomUUID());
        users.setAvatarUrl(DefaultUserConstant.DEFAULT_USER_AVATAR);
        save(users);
        return users.getId().intValue();
    }
}




